/*
 * @Description: 数据同步服务
 * @Author: duan_shuangjun 丶
 * @Date: 2025-01-27 13:30:00
 * @LastEditTime: 2025-09-17 18:21:13
 */
import { syncData } from '@/api/dataSync'
import DataSyncProgressService from '@/components/dataSyncProgress'
import { LocalStorage } from '@/utils/storage'

// 同步表配置
interface SyncTableConfig {
    step: number
    status: string
    table: string
    description: string
}

// 同步结果
interface SyncResult {
    success: boolean
    table: string
    message: string
    data?: any
    error?: any
}

// 同步进度回调
type ProgressCallback = (step: number, total: number, status: string) => void

class DataSyncService {
    private progressInstance: any = null
    private isRunning = false

    // 同步表配置
    private readonly syncTables: SyncTableConfig[] = [
        { step: 10, status: '同步桌台表...', table: 'store_shop_desk', description: '桌台基础信息' },
        { step: 20, status: '同步桌台订单表...', table: 'store_shop_desk_order', description: '桌台订单数据' },
        { step: 30, status: '同步菜品表...', table: 'store_shop_food', description: '菜品基础信息' },
        { step: 40, status: '同步菜品绑定表...', table: 'store_shop_food_bind', description: '门店菜品绑定' },
        { step: 50, status: '同步菜品SKU表...', table: 'store_shop_food_sku', description: '菜品规格信息' },
        { step: 60, status: '同步桌台使用记录表...', table: 'store_shop_desk_record', description: '桌台使用历史' },
        { step: 70, status: '同步菜品订单表...', table: 'store_shop_desk_order_food', description: '菜品订单详情' },
        { step: 80, status: '同步打印机表...', table: 'store_shop_printer', description: '打印机配置' },
        { step: 90, status: '同步打印机设置表...', table: 'store_shop_printer_setting', description: '打印机参数' },
        { step: 100, status: '同步电脑表...', table: 'store_shop_computer', description: '电脑设备信息' }
    ]

    /**
     * 开始数据同步
     * @param onProgress 进度回调函数
     * @returns Promise<SyncResult[]>
     */
    async startSync(onProgress?: ProgressCallback): Promise<SyncResult[]> {
        if (this.isRunning) {
            throw new Error('数据同步正在进行中，请勿重复操作')
        }

        this.isRunning = true
        const results: SyncResult[] = []

        try {
            // 显示进度条
            this.progressInstance = await DataSyncProgressService.show({
                totalSteps: 100,
                currentStep: 0,
                statusText: '开始同步数据...'
            })

            // 执行数据同步
            for (let i = 0; i < this.syncTables.length; i++) {
                const { step, status, table, description } = this.syncTables[i]

                console.log(`开始同步第 ${i + 1}/${this.syncTables.length} 个表: ${table} (${description})`)

                // 更新进度
                this.updateProgress(step, 100, status, onProgress)

                // 调用同步接口
                const result = await this.syncTable(table, description)
                results.push(result)

                // 模拟同步延迟
                await this.delay(500)
            }

            // 延迟关闭进度条
            setTimeout(() => {
                this.closeProgress()
            }, 1000)

            return results

        } catch (error) {
            console.error('数据同步过程出错:', error)
            this.closeProgress()
            throw error
        } finally {
            this.isRunning = false
        }
    }

    /**
     * 同步单个表
     * @param table 表名
     * @param description 表描述
     * @returns Promise<SyncResult>
     */
    private async syncTable(table: string, description: string): Promise<SyncResult> {
        try {
            console.log(`正在同步表: ${table}`)

            const syncResult = await syncData({
                userId: LocalStorage.get('userId'),
                token: LocalStorage.get('token'),
                table_name: table
            })

            console.log(`${table} 同步成功:`, syncResult)

            // 将数据批量写入本地数据库
            await this.writeToLocal(table, syncResult?.data)

            return {
                success: true,
                table,
                message: `${description}同步成功`,
                data: syncResult
            }

        } catch (error) {
            console.error(`${table} 同步失败:`, error)

            return {
                success: false,
                table,
                message: `${description}同步失败`,
                error
            }
        }
    }

    /**
     * 将接口返回的数据写入本地 SQLite（通过 IPC 调用主进程批量入库）
     * - 为保证通用性，这里兼容 data.list 或 data 的两种返回结构
     */
    private async writeToLocal(table: string, data: any) {
        try {
            // 兼容多种返回结构：list/rows/items/records/data 以及直接数组
            let rows: any[] = []
            if (Array.isArray(data)) rows = data
            else if (Array.isArray(data?.list)) rows = data.list
            else if (Array.isArray(data?.rows)) rows = data.rows
            else if (Array.isArray(data?.items)) rows = data.items
            else if (Array.isArray(data?.records)) rows = data.records
            else if (Array.isArray(data?.data)) rows = data.data

            console.groupCollapsed(`[DataSync] 入库准备 → ${table}`)
            console.log('payload keys:', data ? Object.keys(data) : 'no data object')
            console.log('rows length:', rows?.length || 0)
            console.groupEnd()

            if (!rows || rows.length === 0) {
                console.warn(`[${table}] 无数据可写入，跳过入库`)
                return
            }
            let result: any

            switch (table) {
                // 桌台相关
                case 'store_shop_desk':
                    result = await window.api.invoke('desk', 'batchUpsert', { desks: rows })
                    break
                case 'store_shop_desk_order':
                    result = await window.api.invoke('desk', 'order/batchUpsert', { orders: rows })
                    break

                // 菜品相关
                case 'store_shop_food':
                    result = await window.api.invoke('desk', 'food/batchUpsert', { foods: rows })
                    break
                case 'store_shop_food_bind':
                    result = await window.api.invoke('desk', 'foodBind/batchUpsert', { binds: rows })
                    break
                case 'store_shop_food_sku':
                    result = await window.api.invoke('desk', 'foodSku/batchUpsert', { skus: rows })
                    break

                // 设备相关
                case 'store_shop_printer':
                    result = await window.api.invoke('desk', 'printer/batchUpsert', { printers: rows })
                    break
                case 'store_shop_computer':
                    result = await window.api.invoke('desk', 'computer/batchUpsert', { computers: rows })
                    break
                case 'store_shop_printer_setting':
                    result = await window.api.invoke('desk', 'printerSetting/batchUpsert', { printerSettings: rows })
                    break

                // 暂未接入入库逻辑的表，先跳过
                case 'store_shop_desk_record':
                    result = await window.api.invoke('desk', 'record/batchUpsert', { records: rows })
                    break
                case 'store_shop_desk_order_food':
                    result = await window.api.invoke('desk', 'orderFood/batchUpsert', { orderFoods: rows })
                    break

                default:
                    console.warn(`未知表 ${table}，未执行入库`)
            }

            console.log('result:', result)
        } catch (e: any) {
            console.error(`写入本地库失败 [${table}]：`, e?.message || e, e)
        }
    }

    /**
     * 更新进度
     * @param step 当前步骤
     * @param total 总步骤
     * @param status 状态文本
     * @param onProgress 进度回调
     */
    private updateProgress(step: number, total: number, status: string, onProgress?: ProgressCallback) {
        if (this.progressInstance) {
            this.progressInstance.setProgress(step, total, status)
        }

        if (onProgress) {
            onProgress(step, total, status)
        }

        console.log(`进度更新: ${step}/${total} (${Math.round((step / total) * 100)}%) - ${status}`)
    }

    /**
     * 关闭进度条
     */
    private closeProgress() {
        if (this.progressInstance) {
            this.progressInstance.close()
            this.progressInstance = null
        }
    }

    /**
     * 延迟函数
     * @param ms 延迟毫秒数
     */
    private delay(ms: number): Promise<void> {
        return new Promise(resolve => setTimeout(resolve, ms))
    }

    /**
     * 获取同步状态
     */
    getSyncStatus(): boolean {
        return this.isRunning
    }

    /**
     * 停止同步
     */
    stopSync() {
        this.isRunning = false
        this.closeProgress()
    }

    /**
     * 获取同步表配置
     */
    getSyncTables(): SyncTableConfig[] {
        return [...this.syncTables]
    }

    /**
     * 批量同步指定表
     * @param tables 要同步的表名数组
     * @param onProgress 进度回调
     */
    async syncSpecificTables(tables: string[], onProgress?: ProgressCallback): Promise<SyncResult[]> {
        if (this.isRunning) {
            throw new Error('数据同步正在进行中，请勿重复操作')
        }

        this.isRunning = true
        const results: SyncResult[] = []

        try {
            // 显示进度条
            this.progressInstance = await DataSyncProgressService.show({
                totalSteps: tables.length * 10,
                currentStep: 0,
                statusText: '开始同步指定表...'
            })

            for (let i = 0; i < tables.length; i++) {
                const table = tables[i]
                const config = this.syncTables.find(t => t.table === table)

                if (config) {
                    const step = (i + 1) * 10
                    this.updateProgress(step, tables.length * 10, config.status, onProgress)

                    const result = await this.syncTable(table, config.description)
                    results.push(result)

                    await this.delay(500)
                }
            }

            setTimeout(() => {
                this.closeProgress()
            }, 1000)

            return results

        } catch (error) {
            console.error('指定表同步过程出错:', error)
            this.closeProgress()
            throw error
        } finally {
            this.isRunning = false
        }
    }
}

// 导出单例实例
export default new DataSyncService()
